// ============================================================================
// 性能监控 Hook
// ============================================================================

import { useEffect, useRef, useState, useCallback } from 'react'

// ============================================================================
// 类型定义
// ============================================================================

export interface PerformanceMetrics {
  renderTime: number
  memoryUsage?: {
    used: number
    total: number
    percentage: number
  } | undefined
  fps: number
  componentCount: number
  timestamp: number
}

export interface RenderMetrics {
  componentName: string
  renderCount: number
  averageRenderTime: number
  lastRenderTime: number
  maxRenderTime: number
  minRenderTime: number
}

// ============================================================================
// 性能监控Hook
// ============================================================================

export function usePerformanceMonitor(componentName?: string) {
  const renderCountRef = useRef(0)
  const renderTimesRef = useRef<number[]>([])
  const lastRenderTimeRef = useRef(0)
  const [metrics, setMetrics] = useState<PerformanceMetrics | null>(null)

  // 记录渲染开始时间
  const renderStartTime = useRef(performance.now())

  // 更新渲染开始时间
  useEffect(() => {
    renderStartTime.current = performance.now()
  })

  // 记录渲染完成
  useEffect(() => {
    const renderEndTime = performance.now()
    const renderTime = renderEndTime - renderStartTime.current
    
    renderCountRef.current++
    renderTimesRef.current.push(renderTime)
    lastRenderTimeRef.current = renderTime

    // 保持最近100次渲染记录
    if (renderTimesRef.current.length > 100) {
      renderTimesRef.current.shift()
    }

    // 更新性能指标
    updateMetrics()
  })

  const updateMetrics = useCallback(() => {
    const now = performance.now()
    
    // 计算平均渲染时间
    const avgRenderTime = renderTimesRef.current.length > 0
      ? renderTimesRef.current.reduce((sum, time) => sum + time, 0) / renderTimesRef.current.length
      : 0

    // 获取内存使用情况（如果支持）
    let memoryUsage: { used: number; total: number; percentage: number; } | undefined
    if ('memory' in performance) {
      const memory = (performance as any).memory
      memoryUsage = {
        used: Number(memory.usedJSHeapSize) || 0,
        total: Number(memory.totalJSHeapSize) || 0,
        percentage: memory.totalJSHeapSize > 0
          ? (Number(memory.usedJSHeapSize) / Number(memory.totalJSHeapSize)) * 100
          : 0
      }
    }

    setMetrics({
      renderTime: avgRenderTime,
      memoryUsage,
      fps: calculateFPS(),
      componentCount: renderCountRef.current,
      timestamp: now
    })
  }, [])

  return {
    metrics,
    renderCount: renderCountRef.current,
    averageRenderTime: renderTimesRef.current.length > 0
      ? renderTimesRef.current.reduce((sum, time) => sum + time, 0) / renderTimesRef.current.length
      : 0,
    lastRenderTime: lastRenderTimeRef.current
  }
}

// ============================================================================
// FPS监控Hook
// ============================================================================

export function useFPSMonitor() {
  const [fps, setFPS] = useState(60)
  const frameCountRef = useRef(0)
  const lastTimeRef = useRef(performance.now())
  const animationFrameRef = useRef<number>()

  const updateFPS = useCallback(() => {
    frameCountRef.current++
    const now = performance.now()
    
    if (now - lastTimeRef.current >= 1000) {
      setFPS(Math.round((frameCountRef.current * 1000) / (now - lastTimeRef.current)))
      frameCountRef.current = 0
      lastTimeRef.current = now
    }
    
    animationFrameRef.current = requestAnimationFrame(updateFPS)
  }, [])

  useEffect(() => {
    animationFrameRef.current = requestAnimationFrame(updateFPS)
    
    return () => {
      if (animationFrameRef.current) {
        cancelAnimationFrame(animationFrameRef.current)
      }
    }
  }, [updateFPS])

  return fps
}

// ============================================================================
// 内存监控Hook
// ============================================================================

export function useMemoryMonitor() {
  const [memoryInfo, setMemoryInfo] = useState<{
    used: number
    total: number
    percentage: number
  } | null>(null)

  useEffect(() => {
    const updateMemoryInfo = () => {
      if ('memory' in performance) {
        const memory = (performance as any).memory
        setMemoryInfo({
          used: memory.usedJSHeapSize,
          total: memory.totalJSHeapSize,
          percentage: (memory.usedJSHeapSize / memory.totalJSHeapSize) * 100
        })
      }
    }

    updateMemoryInfo()
    const interval = setInterval(updateMemoryInfo, 1000)

    return () => clearInterval(interval)
  }, [])

  return memoryInfo
}

// ============================================================================
// 组件渲染性能Hook
// ============================================================================

export function useRenderPerformance(componentName: string) {
  const renderMetricsRef = useRef<RenderMetrics>({
    componentName,
    renderCount: 0,
    averageRenderTime: 0,
    lastRenderTime: 0,
    maxRenderTime: 0,
    minRenderTime: Infinity
  })

  const renderStartTimeRef = useRef(0)
  const renderTimesRef = useRef<number[]>([])

  // 记录渲染开始
  useEffect(() => {
    renderStartTimeRef.current = performance.now()
  })

  // 记录渲染结束
  useEffect(() => {
    const renderEndTime = performance.now()
    const renderTime = renderEndTime - renderStartTimeRef.current

    const metrics = renderMetricsRef.current
    metrics.renderCount++
    metrics.lastRenderTime = renderTime
    metrics.maxRenderTime = Math.max(metrics.maxRenderTime, renderTime)
    metrics.minRenderTime = Math.min(metrics.minRenderTime, renderTime)

    renderTimesRef.current.push(renderTime)
    
    // 保持最近50次渲染记录
    if (renderTimesRef.current.length > 50) {
      renderTimesRef.current.shift()
    }

    // 计算平均渲染时间
    metrics.averageRenderTime = renderTimesRef.current.reduce((sum, time) => sum + time, 0) / renderTimesRef.current.length

    // 在开发环境下输出性能警告
    if (process.env.NODE_ENV === 'development' && renderTime > 16) {
      console.warn(`Slow render detected in ${componentName}: ${renderTime.toFixed(2)}ms`)
    }
  })

  return renderMetricsRef.current
}

// ============================================================================
// 长任务监控Hook
// ============================================================================

export function useLongTaskMonitor() {
  const [longTasks, setLongTasks] = useState<PerformanceEntry[]>([])

  useEffect(() => {
    if ('PerformanceObserver' in window) {
      const observer = new PerformanceObserver((list) => {
        const entries = list.getEntries()
        setLongTasks(prev => [...prev, ...entries].slice(-10)) // 保持最近10个长任务
        
        // 在开发环境下输出长任务警告
        if (process.env.NODE_ENV === 'development') {
          entries.forEach(entry => {
            console.warn(`Long task detected: ${entry.duration.toFixed(2)}ms`)
          })
        }
      })

      try {
        observer.observe({ entryTypes: ['longtask'] })
      } catch (error) {
        console.warn('Long task monitoring not supported')
      }

      return () => observer.disconnect()
    }
  }, [])

  return longTasks
}

// ============================================================================
// 工具函数
// ============================================================================

function calculateFPS(): number {
  // 简单的FPS计算，基于requestAnimationFrame
  let fps = 60
  let lastTime = performance.now()
  let frameCount = 0

  const measure = () => {
    frameCount++
    const now = performance.now()
    
    if (now - lastTime >= 1000) {
      fps = Math.round((frameCount * 1000) / (now - lastTime))
      frameCount = 0
      lastTime = now
    }
    
    requestAnimationFrame(measure)
  }

  requestAnimationFrame(measure)
  return fps
}

/**
 * 性能测量装饰器
 */
export function measurePerformance(name: string) {
  return function (target: any, propertyName: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value

    descriptor.value = function (...args: any[]) {
      const startTime = performance.now()
      
      const result = originalMethod.apply(this, args)
      
      if (result instanceof Promise) {
        return result.finally(() => {
          const endTime = performance.now()
          console.log(`${name} took ${endTime - startTime} milliseconds`)
        })
      } else {
        const endTime = performance.now()
        console.log(`${name} took ${endTime - startTime} milliseconds`)
        return result
      }
    }

    return descriptor
  }
}

/**
 * 性能分析器
 */
export class PerformanceProfiler {
  private marks: Map<string, number> = new Map()
  private measures: Map<string, number> = new Map()

  mark(name: string) {
    this.marks.set(name, performance.now())
  }

  measure(name: string, startMark: string, endMark?: string) {
    const startTime = this.marks.get(startMark)
    const endTime = endMark ? this.marks.get(endMark) : performance.now()

    if (startTime !== undefined && endTime !== undefined) {
      const duration = endTime - startTime
      this.measures.set(name, duration)
      return duration
    }

    return 0
  }

  getMeasure(name: string): number | undefined {
    return this.measures.get(name)
  }

  getAllMeasures(): Map<string, number> {
    return new Map(this.measures)
  }

  clear() {
    this.marks.clear()
    this.measures.clear()
  }
}

// 全局性能分析器实例
export const globalProfiler = new PerformanceProfiler()
